<?php

namespace App\Http\Middleware;

use App\Services\Service\Helper;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response as BaseResponse;

class HttpReturnMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        /**@var \Illuminate\Http\Response $result * */
        $this->fixRequest($request);
        $result = $next($request);
        $status = intval($result->status());
        if ($status !== 200) {
            $methodName = "handle$status";
            return method_exists($this, $methodName) ?
                call_user_func([$this, $methodName], $result, $request, $status) :
                $this->handleError($result, $request, $status);
        } else {
            return $result;
        }
    }

    /**
     * 特殊情况下, 修复request中json解析失败的问题
     *
     * @param Request $request
     */
    protected function fixRequest(Request &$request)
    {
        $raw = urldecode(file_get_contents('php://input'));
        $data = json_decode(substr($raw, 1), true);
        if (count($data) > 0) {
            $request->merge($data);
        }
    }

    /**
     * 处理错误
     * @param \Illuminate\Http\Response $response
     * @return JsonResponse
     */
    protected function handleError(BaseResponse $response, $request, $statusCode = 500)
    {
        $exceptionHandle = $response->exception;
        $code = $statusCode;
        $exception = [
            'file' => $exceptionHandle->getFile(),
            'line' => $exceptionHandle->getLine(),
            'error_message' => $exceptionHandle->getMessage(),
        ];
        $path = $request->path();
        $guard = 'user';
        $message = $exceptionHandle->getMessage();
        $return_data = compact('code', 'message');
        if (config('app.debug')) {
            $message = $response->status();
            $return_data = compact('code', 'message', 'exception');
        }
        return Helper::errorHandle($request, $message, $guard, $statusCode, $return_data);
    }
}
